home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / guile-ii.src / guile-ii / guile-src / gls / Gmodules.scm < prev    next >
Encoding:
Text File  |  1995-08-03  |  14.5 KB  |  497 lines

  1. ;;;;     Copyright (C) 1994, 1995 Free Software Foundation, Inc.
  2. ;;;; 
  3. ;;;; This program is free software; you can redistribute it and/or modify
  4. ;;;; it under the terms of the GNU General Public License as published by
  5. ;;;; the Free Software Foundation; either version 2, or (at your option)
  6. ;;;; any later version.
  7. ;;;; 
  8. ;;;; This program is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. ;;;; GNU General Public License for more details.
  12. ;;;; 
  13. ;;;; You should have received a copy of the GNU General Public License
  14. ;;;; along with this software; see the file COPYING.  If not, write to
  15. ;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ;;;; 
  17.  
  18. ;; by Miles Bader (bader@gnu.ai.mit.edu)
  19. ;; and Tom Lord (lord@gnu.ai.mit.edu)
  20. ;;
  21.  
  22.  
  23.  
  24. ;;; {Error Handling}
  25. ;;;
  26. ;;; This is the error handler used by the low-level module system.
  27. ;;; It has its own name so that calls are easy to find and change
  28. ;;; later once we know what we are doing.
  29. ;;;
  30.  
  31.  
  32. (define guile:error error)
  33.  
  34.  
  35. ;;; {Low Level Modules}
  36. ;;;
  37. ;;; These are the low level data structures for modules.
  38. ;;;
  39. ;;; (make-module size use-list lazy-binding-proc) => module
  40. ;;; module-{obarray,uses,binder}[|-set!]
  41. ;;; (module? obj) => [#t|#f]
  42. ;;; (module-locally-bound? module symbol) => [#t|#f]
  43. ;;; (module-bound? module symbol) => [#t|#f]
  44. ;;; (module-symbol-locally-interned? module symbol) => [#t|#f]
  45. ;;; (module-symbol-interned? module symbol) => [#t|#f]
  46. ;;; (module-local-variable module symbol) => [#<variable ...> | #f]
  47. ;;; (module-variable module symbol) => [#<variable ...> | #f]
  48. ;;; (module-symbol-binding module symbol opt-value)
  49. ;;;        => [ <obj> | opt-value | an error occurs ]
  50. ;;; (module-make-local-var! module symbol) => #<variable...>
  51. ;;; (module-add! module symbol var) => unspecified
  52. ;;; (module-remove! module symbol) =>  unspecified
  53. ;;; (module-for-each proc module) => unspecified
  54. ;;; the-symhash-module ; a module wrapper for the built-in top level
  55. ;;; (make-scm-module) => module ; a lazy copy of the symhash module
  56. ;;; (set-current-module module) => unspecified
  57. ;;; (current-module) => #<module...>
  58. ;;;
  59. ;;;
  60.  
  61.  
  62. ;;; {and-map, or-map, and map-in-order}
  63. ;;;
  64. ;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...)
  65. ;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...)
  66. ;;; (map-in-order fn lst) is like (map fn lst) but definately in order of lst.
  67. ;;;
  68.  
  69. ;; and-map f l
  70. ;;
  71. ;; Apply f to successive elements of l until exhaustion or f returns #f.
  72. ;; If returning early, return #f.  Otherwise, return the last value returned
  73. ;; by f.  If f has never been called because l is empty, return #t.
  74. ;; 
  75. (define (and-map f lst)
  76.   (let loop ((result #t)
  77.          (l lst))
  78.     (and result
  79.      (or (and (null? l)
  80.           result)
  81.          (loop (f (car l)) (cdr l))))))
  82.  
  83. ;; or-map f l
  84. ;;
  85. ;; Apply f to successive elements of l until exhaustion or while f returns #f.
  86. ;; If returning early, return the return value of f.
  87. ;;
  88. (define (or-map f lst)
  89.   (let loop ((result #f)
  90.          (l lst))
  91.     (or result
  92.     (and (not (null? l))
  93.          (loop (f (car l)) (cdr l))))))
  94.  
  95. ;; map-in-order
  96. ;;
  97. ;; Like map, but guaranteed to process the list in order.
  98. ;;
  99. (define (map-in-order fn l)
  100.   (if (null? l)
  101.       '()
  102.       (cons (fn (car l))
  103.         (map-in-order fn (cdr l)))))
  104.  
  105. ;; DEFINE-MACRO
  106. ;; 
  107. ;; A more schemey version of scm's common-lispy defmacro.  Should also be
  108. ;; more module-safe.
  109. ;; 
  110. (defmacro define-macro (first . rest)
  111.   (let ((name (if (symbol? first) first (car first)))
  112.     (transformer
  113.      (if (symbol? first)
  114.          (car rest)
  115.          `(lambda ,(cdr first) ,@rest))))
  116.     `(define ,name
  117.     (,(lambda (transformer)
  118.         (set! *defmacros* (acons name transformer *defmacros*))
  119.           (defmacro:transformer transformer))
  120.      ,transformer))))
  121.  
  122. ;; This is how modules are printed.
  123. ;; You can re-define it.
  124. ;;
  125. (define (%print-module mod port wr?)
  126.   (display "#<" port)
  127.   (display (or (module-kind mod) "module") port)
  128.   (let ((name (module-name mod)))
  129.     (if name
  130.     (begin
  131.       (display " " port)
  132.       (display name port))))
  133.   (display " " port)
  134.   (display (number->string (object-address mod) 16) port)
  135.   (display ">" port))
  136.  
  137. ;; module-type
  138. ;;
  139. ;; A module is characterized by an obarray in which local symbols
  140. ;; are interned, a list of modules, "uses", from which non-local
  141. ;; bindings can be inherited, and an optional lazy-binder which
  142. ;; is a (THUNK module symbol) which, as a last resort, can provide
  143. ;; bindings that would otherwise not be found locally in the module.
  144. ;;
  145. (define module-type
  146.   (make-record-type 'module '(obarray uses binder eval-thunk name kind)
  147.             (lambda (mod port wr?)
  148.               (%print-module mod port wr?))))
  149.  
  150. ;; make-module &opt size uses
  151. ;;
  152. ;; Create a new module, perhaps with a particular size of obarray
  153. ;; or initial uses list.
  154. ;;
  155. (define module-constructor (record-constructor module-type))
  156.  
  157. (define make-module
  158.     (lambda args
  159.       (let* ((size 1021)
  160.          (uses '())
  161.          (binder #f)
  162.          (answer #f)
  163.          (eval-thunk
  164.           (lambda (symbol define?)
  165.         (if define?
  166.             (module-make-local-var! answer symbol)
  167.             (module-variable answer symbol)))))
  168.  
  169.     (if (> (length args) 0)
  170.         (begin
  171.           (set! size (or (car args) size))
  172.           (set! args (cdr args))))
  173.  
  174.     (if (> (length args) 0)
  175.         (begin
  176.           (set! uses (or (car args) uses))
  177.           (set! args (cdr args))))
  178.  
  179.     (if (> (length args) 0)
  180.         (begin
  181.           (set! binder (or (car args) binder))
  182.           (set! args (cdr args))))
  183.  
  184.     (if (not (null? args))
  185.         (guile:error "Too many args to make-module." args))
  186.  
  187.     (if (not (integer? size))
  188.         (guile:error "Illegal size to make-module." size))
  189.  
  190.     (and (list? uses)
  191.          (or (and-map module? uses)
  192.          (guile:error "Incorrect use list." uses)))
  193.  
  194.     (if (and binder (not (procedure? binder)))
  195.         (guile:error
  196.          "Lazy-binder expected to be a procedure or #f." binder))
  197.  
  198.     (set! answer
  199.           (module-constructor (make-vector size '())
  200.                   uses
  201.                   binder
  202.                   eval-thunk
  203.                   #f
  204.                   #f))
  205.     answer)))
  206.  
  207. (define module-obarray  (record-accessor module-type 'obarray))
  208. (define module-obarray-set! (record-modifier module-type 'obarray))
  209. (define module-uses  (record-accessor module-type 'uses))
  210. (define module-uses-set! (record-modifier module-type 'uses))
  211. (define module-binder (record-accessor module-type 'binder))
  212. (define module-binder-set! (record-modifier module-type 'binder))
  213. (define module-eval-thunk (record-accessor module-type 'eval-thunk))
  214. (define module-eval-thunk-set! (record-modifier module-type 'eval-thunk))
  215. (define module-name (record-accessor module-type 'name))
  216. (define module-set-name! (record-modifier module-type 'name))
  217. (define module-kind (record-accessor module-type 'kind))
  218. (define module-set-kind! (record-modifier module-type 'kind))
  219. (define module? (record-predicate module-type))
  220.  
  221.  
  222. ;;; {Module Searching in General}
  223. ;;;
  224. ;;; We sometimes want to look for properties of a symbol
  225. ;;; just within the obarray of one module.  If the property
  226. ;;; holds, then it is said to hold ``locally'' as in, ``The symbol
  227. ;;; DISPLAY is locally rebound in the module `safe-guile'.''
  228. ;;;
  229. ;;;
  230. ;;; Other times, we want to test for a symbol property in the obarray
  231. ;;; of M and, if it is not found there, try each of the modules in the
  232. ;;; uses list of M.  This is the normal way of testing for some
  233. ;;; property, so we state these properties without qualification as
  234. ;;; in: ``The symbol 'fnord is interned in module M because it is
  235. ;;; interned locally in module M2 which is a member of the uses list
  236. ;;; of M.''
  237. ;;;
  238.  
  239. ;; module-search fn m
  240. ;; 
  241. ;; return the first non-#f result of FN applied to M and then to
  242. ;; the modules in the uses of m, and so on recursively.  If all applications
  243. ;; return #f, then so does this function.
  244. ;;
  245. (define (module-search fn m v)
  246.   (define (loop pos)
  247.     (and (pair? pos)
  248.      (or (module-search fn (car pos) v)
  249.          (loop (cdr pos)))))
  250.   (or (fn m v)
  251.       (loop (module-uses m))))
  252.  
  253.  
  254. ;;; {Is a symbol bound in a module?}
  255. ;;;
  256. ;;; Symbol S in Module M is bound if S is interned in M and if the binding
  257. ;;; of S in M has been set to some well-defined value.
  258. ;;;
  259.  
  260. ;; module-locally-bound? module symbol
  261. ;;
  262. ;; Is a symbol bound (interned and defined) locally in a given module?
  263. ;;
  264. (define (module-locally-bound? m v)
  265.   (let ((var (module-local-variable m v)))
  266.     (and var
  267.      (variable-bound? var))))
  268.  
  269. ;; module-bound? module symbol
  270. ;;
  271. ;; Is a symbol bound (interned and defined) anywhere in a given module
  272. ;; or its uses?
  273. ;;
  274. (define (module-bound? m v)
  275.   (module-search module-locally-bound? m v))
  276.  
  277. ;;; {Is a symbol interned in a module?}
  278. ;;;
  279. ;;; Symbol S in Module M is interned if S occurs in 
  280. ;;; of S in M has been set to some well-defined value.
  281. ;;;
  282. ;;; It is possible to intern a symbol in a module without providing
  283. ;;; an initial binding for the corresponding variable.  This is done
  284. ;;; with:
  285. ;;;       (module-add! module symbol (make-undefined-variable))
  286. ;;;
  287. ;;; In that case, the symbol is interned in the module, but not
  288. ;;; bound there.  The unbound symbol shadows any binding for that
  289. ;;; symbol that might otherwise be inherited from a member of the uses list.
  290. ;;;
  291.  
  292. ;; module-symbol-locally-interned? module symbol
  293. ;; 
  294. ;; is a symbol interned (not neccessarily defined) locally in a given module
  295. ;; or its uses?  Interned symbols shadow inherited bindings even if
  296. ;; they are not themselves bound to a defined value.
  297. ;;
  298. (define (module-symbol-locally-interned? m v)
  299.   (symbol-interned? (module-obarray m) v))
  300.  
  301.  
  302. ;; module-symbol-interned? module symbol
  303. ;; 
  304. ;; is a symbol interned (not neccessarily defined) anywhere in a given module
  305. ;; or its uses?  Interned symbols shadow inherited bindings even if
  306. ;; they are not themselves bound to a defined value.
  307. ;;
  308. (define (module-symbol-interned? m v)
  309.   (module-search module-symbol-locally-interned? m v))
  310.  
  311.  
  312. ;;; {Mapping modules x symbols --> variables}
  313. ;;;
  314.  
  315. ;; module-local-variable module symbol
  316. ;; return the local variable associated with a MODULE and SYMBOL.
  317. ;;
  318. ;;; This function is very important. It is the only function that can
  319. ;;; return a variable from a module other than the mutators that store
  320. ;;; new variables in modules.  Therefore, this function is the location
  321. ;;; of the "lazy binder" hack.
  322. ;;;
  323. ;;; If symbol is defined in MODULE, and if the definition binds symbol
  324. ;;; to a variable, return that variable object.
  325. ;;;
  326. ;;; If the symbols is not found at first, but the module has a lazy binder,
  327. ;;; then try the binder.
  328. ;;;
  329. ;;; If the symbol is not found at all, return #f.
  330. ;;;
  331. (define (module-local-variable m v)
  332.   (or (and (module-symbol-locally-interned? m v)
  333.        (let ((b (symbol-binding (module-obarray m) v)))
  334.          (and (variable? b) b)))
  335.       (and (module-binder m)
  336.        ((module-binder m) m v))))
  337.  
  338. ;; module-variable module symbol
  339. ;; 
  340. ;; like module-local-variable, except search the uses in the 
  341. ;; case V is not found in M.
  342. ;;
  343. (define (module-variable m v)
  344.   (module-search module-local-variable m v))
  345.  
  346.  
  347. ;;; {Mapping modules x symbols --> bindings}
  348. ;;;
  349. ;;; These are similar to the mapping to variables, except that the
  350. ;;; variable is dereferenced.
  351. ;;;
  352.  
  353. ;; module-symbol-binding module symbol opt-value
  354. ;; 
  355. ;; return the binding of a variable specified by name within
  356. ;; a given module, signalling an guile:error if the variable is unbound.
  357. ;; If the OPT-VALUE is passed, then instead of signalling an guile:error,
  358. ;; return OPT-VALUE.
  359. ;;
  360. (define (module-symbol-local-binding m v . opt-val)
  361.   (let ((var (module-local-variable m v)))
  362.     (if var
  363.     (variable-ref var)
  364.     (if (not (null? opt-val))
  365.         (car opt-val)
  366.         (guile:error "Locally unbound variable." v)))))
  367.  
  368. ;; module-symbol-binding module symbol opt-value
  369. ;; 
  370. ;; return the binding of a variable specified by name within
  371. ;; a given module, signalling an guile:error if the variable is unbound.
  372. ;; If the OPT-VALUE is passed, then instead of signalling an guile:error,
  373. ;; return OPT-VALUE.
  374. ;;
  375. (define (module-symbol-binding m v . opt-val)
  376.   (let ((var (module-variable m v)))
  377.     (if var
  378.     (variable-ref var)
  379.     (if (not (null? opt-val))
  380.         (car opt-val)
  381.         (guile:error "Unbound variable." v)))))
  382.  
  383.  
  384.  
  385. ;;; {Adding Variables to Modules}
  386. ;;;
  387. ;;;
  388.  
  389.  
  390. ;; module-make-local-var! module symbol
  391. ;; 
  392. ;; ensure a variable for V in the local namespace of M.
  393. ;; If no variable was already there, then create a new and uninitialzied
  394. ;; variable.
  395. ;;
  396. (define (module-make-local-var! m v)
  397.   (or (module-local-variable m v)
  398.       (begin
  399.     (intern-symbol (module-obarray m) v)
  400.     (let ((answer (make-undefined-variable v)))
  401.       (symbol-set! (module-obarray m) v answer)
  402.       answer))))
  403.  
  404. ;; module-add! module symbol var
  405. ;; 
  406. ;; ensure a particular variable for V in the local namespace of M.
  407. ;;
  408. (define (module-add! m v var)
  409.   (if (not (variable? var))
  410.       (guile:error "Bad variable to module-add!" var))
  411.   (intern-symbol (module-obarray m) v)
  412.   (symbol-set! (module-obarray m) v var))
  413.  
  414.  
  415. ;; module-remove! 
  416. ;; 
  417. ;; make sure that a symbol is undefined in the local namespace of M.
  418. ;;
  419. (define (module-remove! m v)
  420.   (unintern-symbol (module-obarray m) v))
  421.  
  422. ;; MODULE-FOR-EACH -- exported
  423. ;; 
  424. ;; Call PROC on each symbol in MODULE, with arguments of (SYMBOL VARIABLE).
  425. ;;
  426. (define (module-for-each proc module)
  427.   (let ((obarray (module-obarray module)))
  428.     (do ((index 0 (+ index 1))
  429.      (end (vector-length obarray)))
  430.     ((= index end))
  431.       (for-each
  432.        (lambda (bucket)
  433.      (proc (car bucket) (cdr bucket)))
  434.        (vector-ref obarray index)))))
  435.  
  436.  
  437. ;;; {Low Level Bootstrapping}
  438. ;;;
  439.  
  440. ;; make-scm-module 
  441.  
  442. ;; An scm module is a module into which the lazy binder copies variable
  443. ;; bindings from the symhash table.  Newly introduced bindings
  444. ;; are local to this module.   They are not reflected in the symhash
  445. ;; table.
  446. ;;
  447. (define (make-scm-module)
  448.   (make-module 1019 #f
  449.            (lambda (m s)
  450.          (let ((bi (and (symbol-interned? #f s)
  451.                 (builtin-variable s))))
  452.            (and bi
  453.             (variable-bound? bi)
  454.             bi)))))
  455.  
  456. (define the-default-module (make-scm-module))
  457.  
  458. (define default-uses (list the-default-module))
  459.  
  460. ;; the-module
  461. ;; 
  462. ;; the module used by the normalizer to resolve free variables
  463. ;;
  464. (define the-module the-default-module)
  465.  
  466. ;; set-current-module module
  467. ;;
  468. ;; set the current module as viewed by the normalizer.
  469. ;;
  470. (define (set-current-module m)
  471.   (set! the-module m)
  472.   (set! *top-level-lookup-thunk* (and m (module-eval-thunk m)))
  473.   #t)
  474.  
  475.  
  476. ;; current-module
  477. ;;
  478. ;; return the current module as viewed by the normalizer.
  479. ;;
  480. (define (current-module) the-module)
  481.  
  482.  
  483. ;;; {How to Load the User Module System}
  484. ;;;
  485.  
  486. (define (use-modules)
  487.   (for-each
  488.    (lambda (name)
  489.      (load (in-vicinity (implementation-vicinity) name (scheme-file-suffix))))
  490.    '("modops" "extlibs" "libguile" "defmod"))
  491.   (set-current-module *load-module*))
  492.  
  493. (define (gscm-create-top-level) #f)
  494. (define (gscm-destroy-top-level it) #f)
  495.  
  496.  
  497.